local g
if not FileIO.pwd():endsWith("packages/freekill-core") then
  FileIO.cd("packages/freekill-core")
  g=require "server.gameevent"
  FileIO.cd("../..")
else
  g=require "server.gameevent"
end
local Pe=require "packages/jbs2/pokgame/pokegegine"
local T = require "packages/jbs/record/Theorem"
local GameEvent=g:subclass("pokeGameEvent")

GameEvent.PokeRound=100
GameEvent.PokeTurn=101
GameEvent.PokePhase=102

GameEvent.functions[GameEvent.PokeRound] = function(self)
    local room = self.room
    local logic = room.logic
    local p
  
    local isFirstRound = room:getTag("FirstRound")
    if isFirstRound then
      room:setTag("FirstRound", false)
    end
  
    local roundCount = room:getTag("RoundCount")
    roundCount = roundCount + 1
    room:setTag("RoundCount",  roundCount)
    room:doBroadcastNotify("UpdateRoundNum", roundCount)
    -- 强行平局 防止can_trigger报错导致瞬间几十万轮卡炸服务器
    if roundCount >= 9999 then
      room:gameOver("")
    end
  
    if isFirstRound then
      logic:trigger(fk.GameStart, room.current)
    end
  
    logic:trigger(fk.RoundStart, room.current)
    for _, p in ipairs(room.alive_players) do
      local general = Fk.generals[p.general]
      local skills=general.skill_pool or {"poke__siguang","poke__siguang","poke__siguang","poke__siguang"}
      p.request_data = json.encode({
          
          path = "packages/jbs2/qml/skillchoice.qml",
          data = {
            skills, "#pokeskill-choose" 
          },
        })
        p.default_reply = "poke__siguang"
    end
    room:doBroadcastRequest("CustomDialog", room.alive_players)
    for _, p in ipairs(room.alive_players) do
      local choice = p.reply_ready and json.decode(p.client_reply) or p.default_reply
      local skill_name =choice
      
      local skill=Fk.skills[skill_name]
      p.choice=skill
    end
    local tocompare=table.map(room.alive_players,function (p)
      return p
      
    end)
    local players=Pe.whofirest(tocompare[1],tocompare[2])
    for _, p in ipairs(players) do
      local skill=p.choice
    local t=Pe.choicetarget(room,p,skill.istoself)
    if Pe.missjudge(skill,p,t)then
      room:sendLog {
        type = "#skill_correct_log",
        from = p.id,
        arg =skill.name,
      }
      skill:use(nil, t, p, nil)
    else
      room:sendLog {
        type = "#skill_incorrect_log",
        from = p.id,
        arg =skill.name,
        
      }
    end
    end
  
  
    logic:trigger(fk.RoundEnd, p)
  end
T.translate("#skill_correct_log","%from 使用了%arg ")
T.translate("#skill_incorrect_log","%from 使用了%arg，但没有命中")
GameEvent.cleaners[GameEvent.PokeRound] = function(self)
    local room = self.room
  
    for _, p in ipairs(room.players) do
      p:setCardUseHistory("", 0, Player.HistoryRound)
      p:setSkillUseHistory("", 0, Player.HistoryRound)
      for name, _ in pairs(p.mark) do
        if name:find("-round", 1, true) then
          room:setPlayerMark(p, name, 0)
        end
        if name:find("-effectround", 1, true) then
          room:removePlayerMark(p, name, 1)
        end
      end
    end
  

  
    for _, p in ipairs(room.players) do
      p:filterHandcards()
      room:broadcastProperty(p, "MaxCards")
    end
end
--回合和阶段用不到了，以后可能有用
GameEvent.prepare_funcs[GameEvent.PokeTurn] = function(self)
    local room = self.room
    local logic = room.logic
    local player = room.current
  
    if player.rest > 0 and player.rest < 999 then
      room:setPlayerRest(player, player.rest - 1)
      if player.rest == 0 and player.dead then
        room:revivePlayer(player, true, "rest")
      else
        room:delay(50)
      end
    end
  
    if player.dead then return true end
  
    room:sendLog{ type = "$AppendSeparator" }
  
    if not player.faceup then
      player:turnOver()
      return true
    end
  
    return logic:trigger(fk.BeforeTurnStart, player)
  end
  
  GameEvent.functions[GameEvent.PokeTurn] = function(self)
    local room = self.room
    local logic = room.logic
    local phase_table = {Player.RoundStart,
       Player.Start,
       Player.Play,
        Player.Finish, Player.NotActive,
      }
    logic:trigger(fk.TurnStart, room.current)
    room.current:play(phase_table)
  end
  
  GameEvent.cleaners[GameEvent.PokeTurn] = function(self)
    local room = self.room
  
    local current = room.current
    local logic = room.logic
    if self.interrupted then
      if current.phase ~= Player.NotActive then
        local current_phase = current.phase
        current.phase = Player.PhaseNone
        logic:trigger(fk.EventPhaseChanging, current,
          { from = current_phase, to = Player.NotActive }, true)
        current.phase = Player.NotActive
        room:broadcastProperty(current, "phase")
        logic:trigger(fk.EventPhaseStart, current, nil, true)
      end
  
      current.skipped_phases = {}
    end
  
    logic:trigger(fk.TurnEnd, current, nil, self.interrupted)
    logic:trigger(fk.AfterTurnEnd, current, nil, self.interrupted)
  
    for _, p in ipairs(room.players) do
      p:setCardUseHistory("", 0, Player.HistoryTurn)
      p:setSkillUseHistory("", 0, Player.HistoryTurn)
      for name, _ in pairs(p.mark) do
        if name:find("-turn", 1, true) then
          room:setPlayerMark(p, name, 0)
        end
      end
    end
  
    for cid, cmark in pairs(room.card_marks) do
      for name, _ in pairs(cmark) do
        if name:find("-turn", 1, true) then
          room:setCardMark(Fk:getCardById(cid), name, 0)
        end
      end
    end
  
    for _, p in ipairs(room.players) do
      p:filterHandcards()
      room:broadcastProperty(p, "MaxCards")
    end
  end
  
  GameEvent.functions[GameEvent.PokePhase] = function(self)
    local room = self.room
    local logic = room.logic
  
    local player = self.data[1] ---@type Player
    if not logic:trigger(fk.EventPhaseStart, player) then
      if player.phase ~= Player.NotActive then
        logic:trigger(fk.EventPhaseProceeding, player)
  
        switch(player.phase, {
        [Player.PhaseNone] = function()
          error("You should never proceed PhaseNone")
        end,
        [Player.RoundStart] = function()
  
        end,
        [Player.Start] = function()
  
        end,
        [Player.Judge] = function()
          local cards = player:getCardIds(Player.Judge)
          while #cards > 0 do
            local cid = table.remove(cards)
            if not cid then return end
            local card = player:removeVirtualEquip(cid)
            if not card then
              card = Fk:getCardById(cid)
            end
            if table.contains(player:getCardIds(Player.Judge), cid) then
              room:moveCardTo(card, Card.Processing, nil, fk.ReasonPut, self.name)
  
              ---@type CardEffectEvent
              local effect_data = {
                card = card,
                to = player.id,
                tos = { {player.id} },
              }
              room:doCardEffect(effect_data)
              if effect_data.isCancellOut and card.skill then
                card.skill:onNullified(room, effect_data)
              end
            end
          end
        end,
        [Player.Draw] = function()
          local data = {
            n = 2
          }
          room.logic:trigger(fk.DrawNCards, player, data)
          room:drawCards(player, data.n, "game_rule")
          room.logic:trigger(fk.AfterDrawNCards, player, data)
        end,
        [Player.Play] = function()
          player._play_phase_end = false
          while not player.dead do
            logic:trigger(fk.StartPlayCard, player, nil, true)
            room:notifyMoveFocus(player, "PlayCard")
            local result = room:doRequest(player, "PlayCard", player.id)
            if result == "" then break end
  
            local useResult = room:handleUseCardReply(player, result)
            if type(useResult) == "table" then
              room:useCard(useResult)
            end
  
            if player._play_phase_end then
              player._play_phase_end = false
              break
            end
          end
        end,
        [Player.Discard] = function()
          local discardNum = #table.filter(
            player:getCardIds(Player.Hand), function(id)
              local card = Fk:getCardById(id)
              return table.every(room.status_skills[MaxCardsSkill] or Util.DummyTable, function(skill)
                return not skill:excludeFrom(player, card)
              end)
            end
          ) - player:getMaxCards()
          if discardNum > 0 then
            room:askForDiscard(player, discardNum, discardNum, false, "game_rule", false)
          end
        end,
        [Player.Finish] = function()
  
        end,
        })
      end
    end
  end
  
  GameEvent.cleaners[GameEvent.PokePhase] = function(self)
    local room = self.room
    local player = self.data[1]
    local logic = room.logic
  
    if player.phase ~= Player.NotActive then
      logic:trigger(fk.EventPhaseEnd, player, nil, self.interrupted)
      logic:trigger(fk.AfterPhaseEnd, player, nil, self.interrupted)
    else
      player.skipped_phases = {}
    end
  
    for _, p in ipairs(room.players) do
      p:setCardUseHistory("", 0, Player.HistoryPhase)
      p:setSkillUseHistory("", 0, Player.HistoryPhase)
      for name, _ in pairs(p.mark) do
        if name:find("-phase", 1, true) then
          room:setPlayerMark(p, name, 0)
        end
      end
    end
  
    for cid, cmark in pairs(room.card_marks) do
      for name, _ in pairs(cmark) do
        if name:find("-phase", 1, true) then
          room:setCardMark(Fk:getCardById(cid), name, 0)
        end
      end
    end
  
    for _, p in ipairs(room.players) do
      p:filterHandcards()
      room:broadcastProperty(p, "MaxCards")
    end
  end


return GameEvent